package com.jdk.learn.juc._09threadpool;

import java.util.concurrent.*;

/**
 * Created by ricky
 * on 2018/2/2.
 *
 * 一、线程池：提供了一个线程队列(QUEUE),队列中保存所有等待的线程。避免了创建与销毁的额外开销，提高了响应效率。
 *
 * 二、 线程池体系结构：
 *          ---java.util.concurrent.Executor :负责线程的使用和调度的根接口
 *                  ---ExecutorService :子接口，线程池的主要接口
 *                      ---ThreadPoolExecutor : 实现类，
 *                      ---ScheduledExecutorService : 延迟线程池子接口
 *                          ---ScheduledThreadPoolExecutor :  延迟实现类  继承ThreadPoolExecutor 实现ScheduledExecutorService
 *
 * 三、 工具类 Executors
 *      ExecutorService executorService = Executors.newCachedThreadPool(); //无限制的线程池
        ExecutorService executorService2 = Executors.newSingleThreadExecutor(); //只有一个线程的线程池
        ExecutorService executorService3 = Executors.newFixedThreadPool(3); //固定线程为3的线程池

        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(4);//依次还有上述类似的延迟线程池
 */
public class TestThreadPool  {

    /**
     * 线程池学习
     * */
    public static void learn() {

        //线程池底层都是通过ThreadPoolExecutor来创建
        /**
         * public ThreadPoolExecutor(
          int corePoolSize,  //核心线程数
         int maximumPoolSize,//最大线程数
         long keepAliveTime,//保持时间
         TimeUnit unit,//时间单位
         BlockingQueue<Runnable> workQueue//工作队列
         ) {

         this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory()  //线程工厂  new DefaultThreadFactory();  也可以自定义线程工厂
         ,defaultHandler //事件处理策略默认   private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();
         );

         }
         */
        BlockingQueue<Runnable> workQueue=new LinkedBlockingQueue<>();//工作队列
        ExecutorService executor = new ThreadPoolExecutor(4,10,1,TimeUnit.SECONDS,workQueue);
        executor.execute(()->{
            System.out.println("running");
        });
        executor.shutdown();


        /**forkJoin
         * 窃取线程池
         *
         public ForkJoinPool(int parallelism, //并行数  跟核数挂钩
         ForkJoinWorkerThreadFactory factory, //线程工厂
         UncaughtExceptionHandler handler, //异常处理器   java.util.concurrent.ForkJoinPool.common.exceptionHandler
         boolean asyncMode) //模式
         {
         this(checkParallelism(parallelism),
         checkFactory(factory),
         handler,
         asyncMode ? FIFO_QUEUE : LIFO_QUEUE,  //先进先出 或者后进先出  栈和队列
         "ForkJoinPool-" + nextPoolId() + "-worker-" //工作线程前后缀
         );
         checkPermission();
         }

         执行的任务存放在WorkQueue 中进行调度(externalPush(ForkJoinTask<?> task))

         * */
        ExecutorService executorFJ = Executors.newWorkStealingPool();




        executorFJ.shutdown();
    }

    public static void main2(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executorService3 = Executors.newFixedThreadPool(3);

        Future<Object> submit = executorService3.submit(new Callable<Object>() {

            @Override
            public Object call() throws Exception {
                return "eeee";
            }
        });
        System.out.println(submit.get());
        executorService3.shutdown();//优雅的关闭  等待线程执行完毕继续关闭

    }
    public static void main1(String[] args) {
        ExecutorService executorService3 = Executors.newFixedThreadPool(3);

        for (int i = 0; i < 10; i++) {
            executorService3.submit(new Runnable() {
                @Override
                public void run() {
                    //可以看到线程在复用  而不是新的线程
                    System.out.println(Thread.currentThread().getName()+"------------------");
                }
            });
        }
        executorService3.shutdown();//优雅的关闭  等待线程执行完毕继续关闭

    }


    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);

        //延迟一秒执行
        pool.schedule(()->{
            System.out.println("11111");
        },1000,TimeUnit.MILLISECONDS);

        for (int i = 0; i < 10; i++) {
            //延迟一秒执行  可以被复用
            ScheduledFuture<String> schedule = pool.schedule(() -> {
                return Thread.currentThread().getName() + "----->111";
            }, 1000, TimeUnit.MILLISECONDS);

            System.out.println(schedule.get().toString());
        }
        pool.shutdown();
    }
}

